package com.pedro.encoder.input.gl.render.filters;

import android.content.Context;
import android.opengl.GLES20;
import android.opengl.Matrix;
import android.os.Build;
import android.os.SystemClock;
import android.util.Log;

import androidx.annotation.RequiresApi;

import com.pedro.encoder.R;
import com.pedro.encoder.utils.gl.GlUtil;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Random;

/**
 * 水波纹2
 */
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public class WaveFilter extends BaseFilterRender{

    private final float[] squareVertexDataFilter = {
            // X, Y, Z, U, V
            -1f, -1f, 0f, 0f, 0f, //bottom left
            1f, -1f, 0f, 1f, 0f, //bottom right
            -1f, 1f, 0f, 0f, 1f, //top left
            1f, 1f, 0f, 1f, 1f, //top right
    };
    private int program = -1;
    private int aPositionHandle = -1;
    private int aTextureHandle = -1;
    private int uMVPMatrixHandle = -1;
    private int uSTMatrixHandle = -1;

    private int uTouchXY = -1;
    private int uTexSize = -1;
    private int uTime = -1;
    private int uBoundary = -1;
    private int uWaveAmplitude = -1;

    private int uSamplerHandle = -1;
    //pram
    private long frameIndex=0;
    private float touchX=0.0f;
    private float touchY=0.0f;
    private  int interval=90;//时间间隔，每多少毫秒出发一次特效，默认200ms
    private  float waveAmplitude=1f;//时间间隔，每多少毫秒出发一次特效，默认200ms

    private long startTime = System.currentTimeMillis();

    public WaveFilter(){
        squareVertex = ByteBuffer.allocateDirect(squareVertexDataFilter.length * FLOAT_SIZE_BYTES)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer();
        squareVertex.put(squareVertexDataFilter).position(0);
        Matrix.setIdentityM(MVPMatrix, 0);
        Matrix.setIdentityM(STMatrix, 0);
    }

    public static float nextFloat(final float min, final float max) {
        return min + ((max - min) * new Random().nextFloat());
    }
    @Override
    protected void initGlFilter(Context context) {
        String vertexShader = GlUtil.getStringFromRaw(context, R.raw.simple_vertex);
        String fragmentShader =GlUtil.getStringFromRaw(context, R.raw.wave_fragment);
        program = GlUtil.createProgram(vertexShader, fragmentShader);
        aPositionHandle = GLES20.glGetAttribLocation(program, "aPosition");
        aTextureHandle = GLES20.glGetAttribLocation(program, "aTextureCoord");
        uMVPMatrixHandle = GLES20.glGetUniformLocation(program, "uMVPMatrix");
        uSTMatrixHandle = GLES20.glGetUniformLocation(program, "uSTMatrix");

        uTouchXY = GLES20.glGetUniformLocation(program, "u_TouchXY");
        uTexSize = GLES20.glGetUniformLocation(program, "u_TexSize");
        uTime = GLES20.glGetUniformLocation(program, "u_Time");
        uBoundary = GLES20.glGetUniformLocation(program, "u_Boundary");
        uWaveAmplitude = GLES20.glGetUniformLocation(program, "u_WaveAmplitude");

        uSamplerHandle = GLES20.glGetUniformLocation(program, "s_TextureMap");
        startTime=SystemClock.elapsedRealtime();

    }


    @Override
    protected void drawFilter() {
        GLES20.glUseProgram(program);

        squareVertex.position(SQUARE_VERTEX_DATA_POS_OFFSET);
        GLES20.glVertexAttribPointer(aPositionHandle, 3, GLES20.GL_FLOAT, false,
                SQUARE_VERTEX_DATA_STRIDE_BYTES, squareVertex);
        GLES20.glEnableVertexAttribArray(aPositionHandle);

        squareVertex.position(SQUARE_VERTEX_DATA_UV_OFFSET);
        GLES20.glVertexAttribPointer(aTextureHandle, 2, GLES20.GL_FLOAT, false,
                SQUARE_VERTEX_DATA_STRIDE_BYTES, squareVertex);
        GLES20.glEnableVertexAttribArray(aTextureHandle);

        GLES20.glUniformMatrix4fv(uMVPMatrixHandle, 1, false, MVPMatrix, 0);
        GLES20.glUniformMatrix4fv(uSTMatrixHandle, 1, false, STMatrix, 0);

        GLES20.glActiveTexture(GLES20.GL_TEXTURE4);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, previousTexId);
        GLES20.glUniform1i(uSamplerHandle, 4);
        //
        if (SystemClock.elapsedRealtime()-startTime>interval){
            frameIndex+=1;
            startTime=SystemClock.elapsedRealtime();
        }
        float time =frameIndex*1.0f%(150 / 120f);

        touchX=getWidth()*0.5f;
        touchY=getHeight()*0.5f;
        GLES20.glUniform1f(uTime, time);
        GLES20.glUniform2f(uTouchXY, touchX/getWidth(),touchY/getHeight());
        GLES20.glUniform2f(uTexSize, getWidth(),getHeight());
        GLES20.glUniform1f(uBoundary, 0.13f);//建议值0.1-0.2,改值不对外提供参数
        GLES20.glUniform1f(uWaveAmplitude, waveAmplitude);//建议值0.1-0.2,改值不对外提供参数

        GLES20.glActiveTexture(GLES20.GL_TEXTURE4);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, previousTexId);

    }

    @Override
    public void release() {
        GLES20.glDeleteProgram(program);
    }

    /**
     * 0.1-10
     * @param waveAmplitude
     */
    public void setWaveAmplitude(float waveAmplitude) {
        this.waveAmplitude = waveAmplitude;
    }
}
